﻿
#region Get-HyperVSetting

function Get-HyperVSetting
{
    <#
        .Synopsis 
            Gets the HyperV settings from the ComputerName passed.
            
        .Description
            Gets the HyperV settings from the ComputerName passed.
            
        .Parameter ComputerName
            Name of the Computer to get the settings from.
            
        .Example
            Get-HyperVSetting -computername MyHyperVisor
            Description
            -----------
            Gets the HyperV settings from 'MyHyperVisor'
            
        .Example
            $MyHyperVisors | Get-HyperVSetting 
            Description
            -----------
            Gets the HyperV settings from each HyperVisor in the pipeline
    
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
        .System/String
        
        .Notes
            NAME:      Get-HyperVSetting
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    Process 
    {
            $WMISettings = Get-WMIObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementServiceSettingData -Comp $ComputerName
            $myobj = @{
                ComputerName         = $ComputerName
                VirtualMachinePath   = $WMISettings.DefaultExternalDataRoot
                VirtualHardDiskPath  = $WMISettings.DefaultVirtualHardDiskPath
                MaximumMacAddress    = $WMISettings.MaximumMacAddress
                MinimumMacAddress    = $WMISettings.MinimumMacAddress
            }
            $obj = New-Object PSObject -Property $myobj
            $obj.PSTypeNames.Clear()
            $obj.PSTypeNames.Add('BSonPosh.HyperVSetting')
            $obj
    
    }
}
    
#endregion 


#region Set-HyperVSetting

function Set-HyperVSetting
{

    <#
        .Synopsis 
            Sets the HyperV settings from the ComputerName passed.
            
        .Description
            Sets the HyperV settings from the ComputerName passed.
            
        .Parameter ComputerName
            Name of the Computer to set the settings on.
        
        .Parameter VirtualMachinePath
            Default path to put the VMs settings (alias VMPath.)
        
        .Parameter VirtualHardDiskPath
            Default path to put the VMs hard drives (alias VMDisk.)
                    
        .Example
            Set-HyperVSetting -Computername MyHyperVisor -VirtualMachinePath 'C:\VMs' -VirtualHardDiskPath 'C:\VMs\VHDs'
            Description
            -----------
            Sets the HyperV settings on 'MyHyperVisor'
        
        .Example
            Set-HyperVSetting -Computername MyHyperVisor -VMPath 'C:\VMs' -VMDisk 'C:\VMs\VHDs'
            Description
            -----------
            Sets the HyperV settings on 'MyHyperVisor'
            
        .Example
            $MyHyperVisors | Set-HyperVSetting -VirtualMachinePath 'C:\VMs' -VirtualHardDiskPath 'C:\VMs\VHDs'
            Description
            -----------
            Sets the HyperV settings from each HyperVisor in the pipeline
    
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            String
        
        .Notes
            NAME:      Set-HyperVSetting
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding(SupportsShouldProcess=$True)]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Alias("VMPath")]
        [Parameter()]
        [String]$VirtualMachinePath,
        
        [Alias("VMDisk")]
        [Parameter()]
        [String]$VirtualHardDiskPath
        
    )
    Process 
    {
        Write-Verbose " [Set-HyperVSetting] :: Getting Management Service Object on $ComputerName"
        $ManagmentService = Get-WMIObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService -ComputerName $ComputerName
        
        Write-Verbose " [Set-HyperVSetting] :: Getting current Hyper-V Service Settings"
        $HyperVSettings = Get-WMIObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementServiceSettingData -ComputerName $ComputerName
        
        # Setting MachinePath if passed
        if($VirtualMachinePath)
        {
            Write-Verbose " [Set-HyperVSetting] :: Setting DefaultExternalDataRoot to [$VirtualMachinePath]"
            $HyperVSettings.DefaultExternalDataRoot = $VirtualMachinePath
        }
        
        # Setting HardDisk if passed
        if($VirtualHardDiskPath)
        {
            Write-Verbose " [Set-HyperVSetting] :: Setting DefaultVirtualHardDiskPath to [$VirtualHardDiskPath]"
            $HyperVSettings.DefaultVirtualHardDiskPath = $VirtualHardDiskPath
        }
        if($VirtualMachinePath -or $VirtualHardDiskPath)
        {
            Write-Verbose " [Set-HyperVSetting] :: Committing data back to Hyper-V Server"
            if($PSCmdlet.ShouldProcess($WMISettings,"Setting HyperV Settings on $ComputerName"))
            {
                $SettingsValue = $HyperVSettings.psbase.GetText(1)
                Write-Verbose " [Set-HyperVSetting] :: Calling ModifyServiceSettings on `$ManagmentService"
                $Result = $ManagmentService.ModifyServiceSettings($SettingsValue)
                switch -exact ($Result.ReturnValue)
                {
                    0       {$ReturnCode = "Completed with No Error"}
                    4096    {$ReturnCode = "Method Parameters Checked - Job Started (4096)"}
                    32768   {$ReturnCode = "Failed (32768)"}
                    32769   {$ReturnCode = "Access Denied (32769)"}
                    32770   {$ReturnCode = "Not Supported (32770)"}
                    32771   {$ReturnCode = "Status is unknown (32771)"}
                    32772   {$ReturnCode = "Timeout (32772)"}
                    32773   {$ReturnCode = "Invalid parameter (32773)"}
                    32774   {$ReturnCode = "System is in used (32774)"}
                    32775   {$ReturnCode = "Invalid state for this operation (32775)"}
                    32776   {$ReturnCode = "Incorrect data type (32776)"}
                    32777   {$ReturnCode = "System is not available (32777)"}
                    32778   {$ReturnCode = "Out of memory (32778)"}
                }
                Write-Verbose " [Set-HyperVSetting] :: ReturnCode = '$ReturnCode'"
            }
        }
        
        Write-Verbose " [Set-HyperVSetting] :: Getting Hyper-V Settings"
        Get-HyperVSetting -ComputerName $ComputerName
    }
}
    
#endregion 


#region Test-PSRemoting

function Test-PSRemoting 
{ 
    Param(
        [alias('dnsHostName')]
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName
    )
    
    Process
    {
        Write-Verbose " [Test-PSRemoting] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        
        try 
        { 
            
            $result = Invoke-Command -ComputerName $computername { 1 } -ErrorAction SilentlyContinue
            
            if($result -eq 1 )
            {
                return $True
            }
            else
            {
                return $False
            }
            
        } 
        catch 
        { 
            return $False 
        } 
    }
} 

#endregion